#include "RT.h"

#include <vector>

// map<id, <dist,via>>
//	map<int,pair<int,int>> _table;W
//	int _owner;

RT::RT(vector<int> nodes, int ownerId) {
	MAX_DIST = 10000;
	_owner = ownerId;
	_nodes = nodes;
	for (int i = 0; i < _nodes.size(); ++i) {
		//if not same node's RT
		if (_nodes[i] != _owner) {
			pair<int, int> way(MAX_DIST, -1);
			pair<int, pair<int, int> > entry(_nodes[i], way);
			_table.insert(entry);

			//			pair <int,Node*> p1 (nid,node);
			//			_nodes.insert(p1);
		} else { //entry of node's self
			pair<int, int> way(0, _nodes[i]);
			pair<int, pair<int, int> > entry(_nodes[i], way);
			_table.insert(entry);
		}
	}
}
RT::~RT() {

}
/*
 * Reset RT tables when
 */
void RT::Reset() {
	map<int, pair<int, int> >::iterator it;
	for (it = _table.begin(); it != _table.end(); ++it) {
		//if not same node's RT
		if (it->first != _owner) {
			pair<int, int> way(MAX_DIST, -1);
			it->second = way;
		} else { //entry of node's self
			pair<int, int> way(0, _owner);
			it->second = way;
		}
	}
}

void RT::printRT() {
	cout << "RT for node: " << _owner << endl;
	cout << "==============" << _owner << endl;
	map<int, pair<int, int> >::iterator it;
	cout << "ID	|" << "dist	|" << "via" << endl;
	cout << "__________________________" << endl;
	for (it = _table.begin(); it != _table.end(); ++it) {
		cout << it->first << "	|" << (it->second).first << "	|"
				<< (it->second).second << endl;
		cout << "__________________________" << endl;
	}
	cout << endl;
}

/* updates its values by the new RT according to algorithm
 * nDist = neighbor distance
 * */
bool RT::update(RT* neighborRT) {
	int dist;
	int nDist;
	int via;
	bool changed = false;
	map<int, pair<int, int> >::iterator it;
	map<int, pair<int, int> >::iterator nit;
	nit = neighborRT->_table.begin();
	// loop for each node in graph
	for (it = _table.begin(); it != _table.end(); ++it, ++nit) {
		via = (it->second).second;
		dist = (it->second).first;
		nDist = (nit->second).first;
		// if sender is a node I'm going through- update anyway dist(first) +1
		//		if ( via == neighborRT->getID())
		//		{
		//			(it->second).first = nDist +1;
		//			changed = true;
		//		}
		//		else
		//{ // update only if shorter distance
		if (dist > nDist + 1) {
			(it->second).first = nDist + 1;
			(it->second).second = neighborRT->getID();
			changed = true;
		}
	}

	return changed;
}

int RT::getID() {
	return _owner;
}

int RT::getSize() {
	return _nodes.size();
}

